#include <WiFiManager.h>
#include <ESP8266WiFi.h>           
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266_Seniverse.h>
#include <NTPClient.h>
#include <TFT_eSPI.h>
#include <SPI.h>
#include <Ticker.h>
#include <TFT_eFEX.h>   
#include <PubSubClient.h>

#include"zhu.h"
#include"font.h"
#include"gif.h"

TFT_eSPI tft = TFT_eSPI();
TFT_eFEX  fex = TFT_eFEX(&tft); 

String reqUserKey = "";   // 私钥                                写你自己的心知天气接口
String reqLocation = "";            // 城市
String reqUnit = "c";                      // 摄氏/华氏
WeatherNow weatherNow;  // 建立WeatherNow对象用于获取心知天气信息

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp1.aliyun.com",60*60*8, 30*60*1000);

Ticker ticker;// 建立Ticker用于实现定时功能
int count=0;    // 计数用变量
int a;
int b=1;
int c=0;
int d=0;
char e[20]={};
int e1;

const char* mqttServer = "";   //mqtt服务器域名，写自己的

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

void setup()
{
  
   Serial.begin(9600);
   tft.begin();
   tft.setSwapBytes(true);
   tft.setRotation(0);  // portrait
   tft.fillScreen(0xffff); //用某一颜色填充屏幕
   kaiji();

  if (!SPIFFS.begin()) {
    Serial.println("SPIFFS initialisation failed!");
    while (1) yield(); // Stay here twiddling thumbs waiting
  }
  
   WiFiManager wifiManager;
   wifiManager.autoConnect("AutoConnectAP");
    
   weatherNow.config(reqUserKey, reqLocation, reqUnit);
  
   timeClient.begin();
  
   ticker.attach(1, sayHi);
   

  weatherNow.update();  // 更新天气信息
  a=weatherNow.getDegree();

  // 设置MQTT服务器和端口号
  mqttClient.setServer(mqttServer, 1883);
  // 设置MQTT订阅回调函数
  mqttClient.setCallback(receiveCallback);

  // 连接MQTT服务器
  connectMQTTserver();

   tft.fillScreen(0xffff);
   tft.setTextSize(1); 
  
}



void loop() {

if (mqttClient.connected()) { // 如果开发板成功连接服务器
    mqttClient.loop();          // 处理信息以及心跳
} else {                      // 如果开发板未能成功连接服务器
    connectMQTTserver();        // 则尝试连接服务器
}


if(b==1)
{
if(count>=5)
{
  tianqi();
  count=0;
  tft.fillScreen(0xffff);

}
  shijian();
  zhuye();
}

if(c==1)
{
  jpg();
  c=0;  d=0; b=1;
}

if(d==1)
{
  liuyan();
  
}

}


void sayHi(){
  count++;    
}

void zhuye()
{
  tft.drawLine(160,40, 240, 40, 0x3dff);
  tft.drawLine(160,0, 160, 240,TFT_PINK);
  tft.drawLine(160,106, 240, 106,0x3dff);
  tft.drawLine(160,172, 240, 172,0x3dff);

  tft.setTextColor(0x3dff);       //99ccff  3cff b3   1:3d
  tft.setTextSize(3); 
  tft.setCursor(165,65,1); //wen du
  tft.print(a);
  tft.setTextSize(3); 
  tft.setCursor(220,65,1);
  tft.println("C");
  tft.setTextSize(2); 
  tft.setCursor(205,65,1);
  tft.println("^");

  tft.pushImage(162,175,70,62,you);

  
  tft.pushImage(0,100,110,140,IMG00000);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00001);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00002);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00003);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00004);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00005);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00006);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00007);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00008);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00009);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00010);
  delay(100);
  tft.pushImage(0,100,110,140,IMG00011);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00012);
  delay(200);
  tft.pushImage(0,100,110,140,IMG00013);
  delay(200);
  
}

void tianqi()
{
  weatherNow.update();  // 更新天气信息
  //Serial.print("Temperature: ");
  //Serial.println(weatherNow.getDegree());     // 获取当前温度数值  
  a=weatherNow.getDegree();

}


void shijian()
{
  
  timeClient.update();
  unsigned long epochTime = timeClient.getEpochTime();
  //Serial.println(timeClient.getHours());
  //Serial.println(timeClient.getMinutes());
  
    int weekDay = timeClient.getDay();
    Serial.print("Week Day: ");
    Serial.println(weekDay);
    struct tm *ptm = gmtime ((time_t *)&epochTime);
    int monthDay = ptm->tm_mday;
    //Serial.print("Month day: ");
    //Serial.println(monthDay);
    int currentMonth = ptm->tm_mon+1;
    //Serial.print("Month: ");
    //Serial.println(currentMonth);
    
  tft.setTextColor(TFT_PINK);
  tft.setTextSize(1); 

if(timeClient.getHours()<10)
{
  tft.setCursor(0, 30, 6);
  tft.println("0");
  tft.setCursor(31, 30, 6);
  tft.print(timeClient.getHours());

}
else
{
  tft.setCursor(0, 30, 6);
  tft.print(timeClient.getHours());
}

if(timeClient.getMinutes()<10)
{
  tft.setCursor(85, 30, 6);
  tft.println("0");
  tft.setCursor(116, 30, 6);
  tft.print(timeClient.getMinutes());
}
else
{
  tft.setCursor(85, 30, 6);
  tft.print(timeClient.getMinutes());
}

  tft.setCursor(65, 30, 6);
  tft.println(":");



  tft.setTextColor(0x3dff);
  tft.setTextSize(1); 
  tft.setCursor(163,20,4);
  tft.print(currentMonth);

  tft.setCursor(205, 20, 4);
  tft.print(monthDay);

  tft.setCursor(195, 20, 4);
  tft.println("/");

  
  if(weekDay==1)
  {
  tft.setTextSize(3); 
  tft.setCursor(170,130,1);
  tft.println("Mon");
  }
  if(weekDay==2)
  {
  tft.setTextSize(3); 
  tft.setCursor(170,130,1);
  tft.println("Tue");
  }
    if(weekDay==3)
  {
  tft.setTextSize(3); 
  tft.setCursor(170,130,1);
  tft.println("Wed");
  }
    if(weekDay==4)
  {
  tft.setTextSize(3); 
  tft.setCursor(170,130,1);
  tft.println("Thur");
  }
    if(weekDay==5)
  {
  tft.setTextSize(3); 
  tft.setCursor(170,130,1);
  tft.println("Fri");
  }
    if(weekDay==6)
  {
  tft.setTextSize(3); 
  tft.setCursor(170,130,1);
  tft.println("Sat");
  }
    if(weekDay==0)
  {
  tft.setTextSize(3); 
  tft.setCursor(170,130,1);
  tft.println("Sun");
  }


}

void kaiji()
{
  tft.pushImage(60,40,131,93,zhu);
  showMyFonts32(80,130,"肥猪猪",TFT_PINK);
  
  tft.setTextColor(TFT_PINK);
  tft.setCursor(20, 170, 2);
  tft.setTextSize(2); 
  tft.println("Connect wifi to");
  tft.setCursor(20, 200, 2);
  tft.println("kaiji");
}


void jpg()
{
  tft.fillScreen(TFT_BLACK);
  fex.drawJpeg("/1.jpg", 0, 30);
  delay(1000);

  fex.drawJpeg("/2.jpg", 0, 30);
  delay(1000);

  fex.drawJpeg("/4.jpg", 0, 30);
  delay(1000);
  
  fex.drawJpeg("/5.jpg", 0, 30);
  delay(1000);

  fex.drawJpeg("/6.jpg", 0, 30);
  delay(1000);  
 
  fex.drawJpeg("/7.jpg", 0, 30);
  delay(1000);

  fex.drawJpeg("/8.jpg", 0, 30);
  delay(1000);  

  fex.drawJpeg("/9.jpg", 0, 30);
  delay(1000);  
  
  fex.drawJpeg("/10.jpg", 0, 30);
  delay(1000);  

  fex.drawJpeg("/11.jpg", 0, 30);
  delay(1000);

  fex.drawJpeg("/c.jpg", 0, 30);
  delay(1000);  
  
}

void liuyan()
{
    int l=40;
    int h=90;
    tft.fillScreen(0xffff);
    tft.pushImage(0,0,150,49,liu);
    
    tft.setTextColor(TFT_BLACK);
    tft.setTextSize(2); 
    for(int i=0;i<e1;i++)
    {
    tft.setCursor(l, h, 2);
    tft.print(e[i]);
    l=l+20;
    if(l==240)
    {
        h=h+30;
        l=40;
    }
    
    }
    delay(1000);
}





void showMyFont32(int32_t x, int32_t y, const char c[3], uint32_t color) {
  for (int k = 0; k < 2; k++)// 根据字库的字数调节循环的次数
    if (hanzi[k].Index[0] == c[0] && hanzi[k].Index[1] == c[1] && hanzi[k].Index[2] == c[2])
   {
        tft.drawBitmap(x, y, hanzi[k].hz_Id, hanzi[k].hz_width, 32,color);
   }
}

void showMyFonts32(int32_t x, int32_t y, const char str[], uint32_t color) {
  int x0 = x;
  for (int i = 0; i < strlen(str); i += 3) {
    showMyFont32(x0, y, str+i, color);
    x0 += 30;
 }
}


void connectMQTTserver(){
  // 根据ESP8266的MAC地址生成客户端ID（避免与其它ESP8266的客户端ID重名）
  String clientId = "esp8266-" + WiFi.macAddress();

  // 连接MQTT服务器
  if (mqttClient.connect(clientId.c_str())) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address:");
    Serial.println(mqttServer);
    Serial.println("ClientId: ");
    Serial.println(clientId);
    subscribeTopic(); // 订阅指定主题
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(5000);
  }   
}

// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message Received [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println("");
  Serial.print("Message Length(Bytes) ");
  Serial.println(length);

  for(int i=0; i < length; i++)
  {
  e[i]=char(payload[i]);
  Serial.println(e[i]);
  }

  e1=length;

  if ((char)payload[0] == '1')
  {     // 如果收到的信息以“1”为开始
  b=0;
  c=1;                             //xiangce
  d=0;
    
  }

  if ((char)payload[0] == '2')
  {     // 如果收到的信息以“2”为开始
    b=0;                                 //liuyan
    c=0;
    d=1;
  }

  if ((char)payload[0] == '3')
  {     // 如果收到的信息以“2”为开始      //zhuye
    b=1;
    c=0;
    d=0;
  }


}

// 订阅指定主题
void subscribeTopic(){

  // 建立订阅主题。主题名称以Taichi-Maker-Sub为前缀，后面添加设备的MAC地址。
  // 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时，所订阅的主题名称不同
  String topicString = "1";
  char subTopic[topicString.length() + 1];  
  strcpy(subTopic, topicString.c_str());
  
  // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
  if(mqttClient.subscribe(subTopic)){
    Serial.println("Subscrib Topic:");
    Serial.println(subTopic);
  } else {
    Serial.print("Subscribe Fail...");
  }  
}
